<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
  </head>
  <body>
    <div>
      <input type="text" placeholder="输入文本" />
      <select id="voiceSelect">
        <option value="male">男生</option>
        <option value="female">女生</option>
        <option value="shenteng">沈腾</option>
      </select>
      <button>开始播放语音</button>
    </div>
  </body>
  <script>
    const btn = document.querySelector('button')
    const ipt = document.querySelector('input')
    const voiceSelect = document.getElementById('voiceSelect')

    const voiceSettings = {
      male: { pitch: 0.8, rate: 1 },
      female: { pitch: 1.5, rate: 1.2 },
      shenteng: { pitch: 1, rate: 0.9 },
    }

    function speak({ text, pitch, rate, lang, volume }, endEvent, startEvent) {
      if (!window.SpeechSynthesisUtterance) {
        console.warn('当前浏览器不支持文字转语音服务')
        return
      }
      if (!text) {
        return
      }
      const speechUtterance = new SpeechSynthesisUtterance()
      speechUtterance.text = text
      speechUtterance.pitch = pitch
      speechUtterance.rate = rate
      speechUtterance.lang = lang || 'zh-CN'
      speechUtterance.volume = volume || 1
      speechUtterance.onstart = function (e) {
        startEvent && startEvent()
      }
      speechUtterance.onend = function (e) {
        endEvent && endEvent()
      }
      speechSynthesis.speak(speechUtterance)

      return speechUtterance
    }

    btn.addEventListener('click', function () {
      if (!ipt.value) return
      const selectedVoice = voiceSelect.value
      const settings = voiceSettings[selectedVoice]

      speak(
        {
          text: ipt.value,
          pitch: settings.pitch,
          rate: settings.rate,
        },
        function () {
          console.log('语音播放结束')
        },
        function () {
          console.log('语音开始播放')
        }
      )
    })
  </script>
</html>
